<template>
  <demo-content :title="title">
    <p>
      setLineDash 中数字数组分别表示绘制的线条的长度，例如
      <code>[5, 10, 15]</code> 会如下绘制线段：
      <ol>
        <li>绘制 5px 长的线段</li>
        <li>间隔 10px 长度(空白区域)</li>
        <li>绘制 15px 长的线段</li>
        <li>间隔 5px 长度(空白区域)</li>
        <li>绘制 10px 长的线段</li>
        <li>间隔 15px 长度(空白区域)</li>
        <li>...</li>
      </ol>
     </p>
    <canvas ref="canvasRef" width="500" height="500"></canvas>
  </demo-content>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import { text } from "./utils";

const title = "虚线绘制";
// 指定组件上的属性
defineOptions({ title });

const canvasRef = ref<HTMLCanvasElement>();

function drawDotLine(
  ctx: CanvasRenderingContext2D,
  x1: number,
  y1: number,
  x2: number,
  y2: number,
  dotLen: number = 2
) {
  if (dotLen < 1) return;
  const xDiff = x2 - x1;
  const yDiff = y2 - y1;
  const lineLen = Math.sqrt(xDiff * xDiff + yDiff * yDiff);
  if (lineLen < 1) return;
  const dx = (dotLen * xDiff) / lineLen;
  const dy = (dotLen * yDiff) / lineLen;
  ctx.save();
  ctx.beginPath();
  let curX = x1;
  let curY = y1;
  const notOverlap = (x: number, y: number) =>
    (x - x1) * (x2 - x) >= 0 && (y - y1) * (y2 - y) >= 0;
  while (notOverlap(curX, curY)) {
    ctx.moveTo(curX, curY);
    if (notOverlap(curX + dx, curY + dy)) {
      ctx.lineTo(curX + dx, curY + dy);
    } else {
      ctx.lineTo(x2, y2);
    }

    curX += 2 * dx;
    curY += 2 * dy;
    if (curX > 500 || curX < 0) break;
  }
  ctx.stroke();
  ctx.restore();
}

function drawDash(
  ctx: CanvasRenderingContext2D,
  x1: number,
  y1: number,
  x2: number,
  y2: number,
  dashLen: number[] = [2]
) {
  ctx.save();
  ctx.beginPath();
  ctx.setLineDash(dashLen);
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
  ctx.restore();
}

onMounted(() => {
  const canvas = canvasRef.value!;
  const ctx = canvas.getContext("2d")!;
  text.draw(ctx, { x: 30, y: 30, text: "原始方式绘制虚线", fontSize: 16 });
  ctx.strokeStyle = "blue";
  drawDotLine(ctx, 30, 50, 470, 50);
  drawDotLine(ctx, 30, 90, 470, 90, 10);
  drawDotLine(ctx, 30, 130, 470, 130, 15);

  text.draw(ctx, { x: 30, y: 230, text: "使用 setLineDash", fontSize: 16 });
  drawDash(ctx, 30, 250, 470, 250);
  drawDash(ctx, 30, 290, 470, 290, [10]);
  drawDash(ctx, 30, 330, 470, 330, [15]);

  text.draw(ctx, { x: 30, y: 400, text: "setLineDash 测试", fontSize: 16 });
  drawDash(ctx, 30, 440, 370, 440, [5, 10, 15]);
});
</script>

<style src="./default.css" scoped></style>
